// wrapped by build app
define("dojox/widget/FeedPortlet", ["dijit", "dojo", "dojox", "dojo/require!dojox/widget/Portlet,dijit/Tooltip,dijit/form/TextBox,dijit/form/Button,dojox/data/GoogleFeedStore"], function (dijit, dojo, dojox) {
    dojo.provide("dojox.widget.FeedPortlet");
    dojo.require("dojox.widget.Portlet");
    dojo.require("dijit.Tooltip");
    dojo.require("dijit.form.TextBox");
    dojo.require("dijit.form.Button");
    dojo.require("dojox.data.GoogleFeedStore");

    dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
        // summary:
        //		A Portlet that loads a XML feed.
        // description:
        //		The feed is displayed as
        //		an unordered list of links.	When a link is hovered over
        //		by the mouse, it displays a summary in a tooltip.

        // local: Boolean
        //		Specifies whether the feed is to be loaded from the same domain as the
        //		page, or a remote domain.	If local is true, then the feed must be an
        //		Atom feed.	If it is false, it can be an Atom or RSS feed.
        local:false,

        // maxResults: Number
        //		The number of results to display from the feed.
        maxResults:5,

        // url: String
        //		The URL of the feed to load.	If this is different to the domain
        //		of the HTML page, local should be set to false.
        url:"",

        // openNew: Boolean
        //		If true, when a link is clicked it will open in a new window.
        //		If false, it will not.
        openNew:true,

        // useFeedTitle: Boolean
        //		If true, the title of the loaded feed is displayed in the title bar of the portlet.
        //		If false, the title remains unchanged.
        showFeedTitle:true,

        postCreate:function () {
            this.inherited(arguments);
            if (this.local && !dojox.data.AtomReadStore) {
                throw Error(this.declaredClass + ": To use local feeds, you must include dojox.data.AtomReadStore on the page.");
            }
        },

        onFeedError:function () {
            // summary:
            //		Called when a feed fails to load successfully.
            this.containerNode.innerHTML = "Error accessing the feed."
        },

        addChild:function (child) {
            this.inherited(arguments);
            var url = child.attr("feedPortletUrl");
            if (url) {
                this.set("url", url);
            }
        },

        _getTitle:function (item) {
            // summary:
            //		Gets the title of a feed item.
            var t = this.store.getValue(item, "title");
            return this.local ? t.text : t;
        },

        _getLink:function (item) {
            // summary:
            //		Gets the href link of a feed item.
            var l = this.store.getValue(item, "link");
            return this.local ? l.href : l;
        },

        _getContent:function (item) {
            // summary:
            //		Gets the summary of a feed item.
            var c = this.store.getValue(item, "summary");
            if (!c) {
                return null;
            }
            if (this.local) {
                c = c.text;
            }
            // Filter out any sneaky scripts in the code
            c = c.split("<script").join("<!--").split("</script>").join("-->");
            c = c.split("<iframe").join("<!--").split("</iframe>").join("-->");
            return c;

        },

        _setUrlAttr:function (url) {
            // summary:
            //		Sets the URL to load.
            this.url = url;
            if (this._started) {
                this.load();
            }
        },

        startup:function () {
            // summary:
            //		Loads the widget.
            if (this.started || this._started) {
                return;
            }

            this.inherited(arguments);

            if (!this.url || this.url == "") {
                throw new Error(this.id + ": A URL must be specified for the feed portlet");
            }
            if (this.url && this.url != "") {
                this.load();
            }
        },

        load:function () {
            // summary:
            //		Loads the feed.
            if (this._resultList) {
                dojo.destroy(this._resultList);
            }
            var store, query;

            // If the feed is on the same domain, use the AtomReadStore,
            // as we cannot be guaranteed that it will be available to
            // Google services.
            if (this.local) {
                store = new dojox.data.AtomReadStore({
                    url:this.url
                });
                query = {};

            } else {
                store = new dojox.data.GoogleFeedStore();
                query = {url:this.url};
            }
            var request = {
                query:query,
                count:this.maxResults,
                onComplete:dojo.hitch(this, function (items) {
                    if (this.showFeedTitle && store.getFeedValue) {
                        var title = this.store.getFeedValue("title");
                        if (title) {
                            this.set("title", title.text ? title.text : title);
                        }
                    }
                    this.generateResults(items);
                }),
                onError:dojo.hitch(this, "onFeedError")
            };

            this.store = store;
            store.fetch(request);
        },

        generateResults:function (items) {
            // summary:
            //		Generates a list of hyperlinks and displays a tooltip
            //		containing a summary when the mouse hovers over them.
            var store = this.store;
            var timer;
            var ul = (this._resultList =
                dojo.create("ul", {"class":"dojoxFeedPortletList"}, this.containerNode));

            dojo.forEach(items, dojo.hitch(this, function (item) {
                var li = dojo.create("li", {
                    innerHTML:'<a href="'
                        + this._getLink(item)
                        + '"'
                        + (this.openNew ? ' target="_blank"' : '')
                        + '>'
                        + this._getTitle(item) + '</a>'
                }, ul);

                dojo.connect(li, "onmouseover", dojo.hitch(this, function (evt) {
                    if (timer) {
                        clearTimeout(timer);
                    }

                    // Show the tooltip after the mouse has been hovering
                    // for a short time.
                    timer = setTimeout(dojo.hitch(this, function () {
                        timer = null;
                        var summary = this._getContent(item);
                        if (!summary) {
                            return;
                        }
                        var content = '<div class="dojoxFeedPortletPreview">'
                            + summary + '</div>'

                        dojo.query("li", ul).forEach(function (item) {
                            if (item != evt.target) {
                                dijit.hideTooltip(item);
                            }
                        });

                        // Hover the tooltip over the anchor tag
                        dijit.showTooltip(content, li.firstChild, !this.isLeftToRight());
                    }), 500);


                }));

                // Hide the tooltip when the mouse leaves a list item.
                dojo.connect(li, "onmouseout", function () {
                    if (timer) {
                        clearTimeout(timer);
                        timer = null;
                    }
                    dijit.hideTooltip(li.firstChild);
                });
            }));

            this.resize();
        }
    });

    dojo.declare("dojox.widget.ExpandableFeedPortlet", dojox.widget.FeedPortlet, {
        // summary:
        //		A FeedPortlet that uses an list of expandable links to display
        //		a feed.	An icon is placed to the left of each item
        //		which, when clicked, toggles the visible state
        //		of the item summary.

        // onlyOpenOne: Boolean
        //		If true, only a single item can be expanded at any given time.
        onlyOpenOne:false,

        generateResults:function (items) {
            // summary:
            //		Generates a list of items, and places an icon beside them that
            //		can be used to show or hide a summary of that item.

            var store = this.store;
            var iconCls = "dojoxPortletToggleIcon";
            var collapsedCls = "dojoxPortletItemCollapsed";
            var expandedCls = "dojoxPortletItemOpen";

            var timer;
            var ul = (this._resultList = dojo.create("ul", {
                "class":"dojoxFeedPortletExpandableList"
            }, this.containerNode));

            // Create the LI elements.	Each LI has two DIV elements, the
            // top DIV contains the toggle icon and title, and the bottom
            // div contains the extended summary.
            dojo.forEach(items, dojo.hitch(this, dojo.hitch(this, function (item) {
                var li = dojo.create("li", {"class":collapsedCls}, ul);
                var upper = dojo.create("div", {style:"width: 100%;"}, li);
                var lower = dojo.create("div", {"class":"dojoxPortletItemSummary", innerHTML:this._getContent(item)}, li);
                dojo.create("span", {
                    "class":iconCls,
                    innerHTML:"<img src='" + dojo.config.baseUrl + "/resources/blank.gif'>"}, upper);
                var a = dojo.create("a", {href:this._getLink(item), innerHTML:this._getTitle(item) }, upper);

                if (this.openNew) {
                    dojo.attr(a, "target", "_blank");
                }
            })));

            // Catch all clicks on the list. If a toggle icon is clicked,
            // toggle the visible state of the summary DIV.
            dojo.connect(ul, "onclick", dojo.hitch(this, function (evt) {
                if (dojo.hasClass(evt.target, iconCls) || dojo.hasClass(evt.target.parentNode, iconCls)) {
                    dojo.stopEvent(evt);
                    var li = evt.target.parentNode;
                    while (li.tagName != "LI") {
                        li = li.parentNode;
                    }
                    if (this.onlyOpenOne) {
                        dojo.query("li", ul).filter(
                            function (item) {
                                return item != li;
                            }).removeClass(expandedCls).addClass(collapsedCls);
                    }
                    var isExpanded = dojo.hasClass(li, expandedCls);
                    dojo.toggleClass(li, expandedCls, !isExpanded);
                    dojo.toggleClass(li, collapsedCls, isExpanded);
                }
            }));
        }
    });


    dojo.declare("dojox.widget.PortletFeedSettings",
        dojox.widget.PortletSettings, {

            // summary:
            //		A Settings widget designed to be used with a dojox.widget.FeedPortlet
            // description:
            //		It provides form items that the user can use to change the URL
            //		for a feed to load into the FeedPortlet.
            //		There are two forms that it can take.
            //
            //		The first is to display a text field, with Load and Cancel buttons,
            //		which is prepopulated with the enclosing FeedPortlet's URL.
            //		If a `<select>` DOM node is used as the source node for this widget,
            //		it displays a list of predefined URLs that the user can select from
            //		to load into the enclosing FeedPortlet.
            //
            // example:
            // |	<div dojoType="dojox.widget.PortletFeedSettings"></div>
            //
            // example:
            // |	<select dojoType="dojox.widget.PortletFeedSettings">
            // |		<option>http://www.dojotoolkit.org/aggregator/rss</option>
            // |		<option>http://dojocampus.org/content/category/podcast/feed/</option>
            // |	</select>

            "class":"dojoxPortletFeedSettings",

            // urls: Array
            //		An array of JSON object specifying URLs to display in the
            //		PortletFeedSettings object. Each object contains a 'url' and 'label'
            //		attribute, e.g.
            //		[{url:'http:google.com', label:'Google'}, {url:'http://dojotoolkit.org', label: 'Dojo'}]
            urls:null,

            // selectedIndex: Number
            //		The selected URL. Defaults to zero.
            selectedIndex:0,

            buildRendering:function () {
                // If JSON URLs have been specified, create a SELECT DOM node,
                // and insert the required OPTION elements.
                var s;
                if (this.urls && this.urls.length > 0) {
                    console.log(this.id + " -> creating select with urls ", this.urls)
                    s = dojo.create("select");
                    if (this.srcNodeRef) {
                        dojo.place(s, this.srcNodeRef, "before");
                        dojo.destroy(this.srcNodeRef);
                    }
                    this.srcNodeRef = s;
                    dojo.forEach(this.urls, function (url) {
                        dojo.create("option", {value:url.url || url, innerHTML:url.label || url}, s);
                    });
                }

                // If the srcNodeRef is a SELECT node, then replace it with a DIV, and insert
                // the SELECT node into that div.
                if (this.srcNodeRef.tagName == "SELECT") {
                    this.text = this.srcNodeRef;
                    var div = dojo.create("div", {}, this.srcNodeRef, "before");
                    div.appendChild(this.text);
                    this.srcNodeRef = div;
                    dojo.query("option", this.text).filter("return !item.value;").forEach("item.value = item.innerHTML");
                    if (!this.text.value) {
                        if (this.content && this.text.options.length == 0) {
                            this.text.appendChild(this.content);
                        }
                        dojo.attr(s || this.text, "value", this.text.options[this.selectedIndex].value);
                    }
                }
                this.inherited(arguments);
            },

            _setContentAttr:function () {

            },

            postCreate:function () {
                console.log(this.id + " -> postCreate");
                if (!this.text) {
                    // If a select node is not being used, create a new TextBox to
                    // edit the URL.
                    var text = this.text = new dijit.form.TextBox({});
                    dojo.create("span", {
                        innerHTML:"Choose Url: "
                    }, this.domNode);
                    this.addChild(text);
                }

                // Add a LOAD button
                this.addChild(new dijit.form.Button({
                    label:"Load",
                    onClick:dojo.hitch(this, function () {
                        // Set the URL of the containing Portlet with the selected URL.
                        this.portlet.attr("url",
                            (this.text.tagName == "SELECT") ? this.text.value : this.text.attr('value'));
                        if (this.text.tagName == "SELECT") {
                            // Set the selected index on the Select node.
                            dojo.some(this.text.options, dojo.hitch(this, function (opt, idx) {
                                if (opt.selected) {
                                    this.set("selectedIndex", idx);
                                    return true;
                                }
                                return false;
                            }));
                        }
                        // Hide the widget.
                        this.toggle();
                    })
                }));

                // Add a CANCEL button, which hides this widget
                this.addChild(new dijit.form.Button({
                    label:"Cancel",
                    onClick:dojo.hitch(this, "toggle")
                }));
                this.inherited(arguments);
            },

            startup:function () {
                // summary:
                //		Sets the portlet associated with this PortletSettings object.
                if (this._started) {
                    return;
                }
                console.log(this.id + " -> startup");
                this.inherited(arguments);

                if (!this.portlet) {
                    throw Error(this.declaredClass + ": A PortletFeedSettings widget cannot exist without a Portlet.");
                }
                if (this.text.tagName == "SELECT") {
                    // Set the initial selected option.
                    dojo.forEach(this.text.options, dojo.hitch(this, function (opt, index) {
                        dojo.attr(opt, "selected", index == this.selectedIndex);
                    }));
                }
                var url = this.portlet.attr("url");
                if (url) {
                    // If a SELECT node is used to choose a URL, ensure that the Portlet's URL
                    // is one of the options.
                    if (this.text.tagName == "SELECT") {
                        if (!this.urls && dojo.query("option[value='" + url + "']", this.text).length < 1) {
                            dojo.place(dojo.create("option", {
                                value:url,
                                innerHTML:url,
                                selected:"true"
                            }), this.text, "first");
                        }
                    } else {
                        this.text.attr("value", url);
                    }
                } else {
                    this.portlet.attr("url", this.get("feedPortletUrl"));
                }
            },

            _getFeedPortletUrlAttr:function () {
                return this.text.value;
            }
        });
});
